package maxinshiSomeipTool20.common.itfSafeSWT;

import org.eclipse.swt.events.*;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Widget;

import java.util.function.Consumer;

/**
 * SWT控件事件监听工具类：提供统一的事件注册接口，支持回调函数机制
 * 支持按钮单击、表格单击、双击、Combo选择等常用事件
 */
public class SWTEventManager {

	/**
     * 为Combo控件设置选中项并执行下拉展开动作
     * 功能：1. 设置指定索引的选项为选中状态 2. 自动展开下拉列表（模拟用户点击下拉箭头的效果）
     * 
     * @param combo 目标Combo控件（必须为非null、未释放状态）
     * @param index 要选中的选项索引（从0开始，-1表示取消选中）
     * @return boolean 操作是否成功（控件无效或索引越界时返回false）
     * 
     * @note 1. 索引校验规则：若index为-1，取消选中；若index在[0, 选项数-1]范围内，选中对应项；否则视为无效
     * @note 2. 下拉展开通过setListVisible(true)实现，部分平台可能因样式限制略有差异
     * @note 3. 操作会触发Combo的选择事件（与用户手动选择行为一致）
     * 
     * 使用示例：
     * // 创建一个包含3个选项的Combo
     * Combo myCombo = SwtGuiComm.createCombo(parent, SWT.READ_ONLY, new String[]{"A", "B", "C"}, -1, 150);
     * // 设置选中索引1（"B"）并展开下拉列表
     * boolean success = SwtGuiComm.setComboSelectionAndDrop(myCombo, 1);
     * if (success) {
     *     System.out.println("已选中并展开下拉列表");
     * }
     */
    public static boolean setComboSelectionAndDrop(Combo combo, int index) {
        // 1. 校验控件有效性
        if (combo == null || combo.isDisposed()) {
            return false;
        }

        int itemCount = combo.getItemCount();
        boolean isIndexValid = (index == -1) || (index >= 0 && index < itemCount);

        // 2. 处理选中逻辑（仅当索引有效时）
        if (isIndexValid) {
            if (index == -1) {
                combo.deselectAll(); // 取消所有选中
            } else {
                combo.select(index); // 选中指定索引项
            }
        } else {
            return false; // 索引无效，直接返回失败
        }

        // 3. 执行下拉展开动作（在UI线程中异步执行，确保显示效果）
        combo.getDisplay().asyncExec(() -> {
            if (!combo.isDisposed()) {
                combo.setListVisible(true); // 展开下拉列表
            }
        });

        return true;
    }
    
    /**
     * 仅为Combo控件设置选中项（不展开下拉列表）
     * 功能：安全设置Combo的选中索引，模拟用户选择选项但不展开列表的行为
     * 
     * @param combo 目标Combo控件（必须为非null、未释放状态）
     * @param index 要选中的选项索引（从0开始，-1表示取消选中）
     * @return boolean 操作是否成功（控件无效或索引越界时返回false）
     * 
     * @note 1. 索引校验规则：
     *        - index = -1 → 取消所有选中（调用deselectAll()）
     *        - 0 ≤ index < 选项数 → 选中对应索引的选项（调用select(index)）
     *        - 其他索引 → 视为无效，返回false
     * @note 2. 操作会正常触发Combo的选择事件（与用户手动选择行为一致）
     * @note 3. 与setComboSelectionAndDrop的区别：本方法仅选中选项，不会展开下拉列表
     * 
     * 使用示例：
     * // 创建包含3个选项的Combo
     * Combo myCombo = SwtGuiComm.createCombo(parent, SWT.READ_ONLY, new String[]{"A", "B", "C"}, -1, 150);
     * // 选中索引1（"B"），不展开下拉列表
     * boolean success = SwtGuiComm.setComboSelection(myCombo, 1);
     * if (success) {
     *     System.out.println("已选中索引1的选项");
     * }
     */
    public static boolean setComboSelection(Combo combo, int index) {
        // 1. 校验控件有效性（避免操作已释放或null的控件）
        if (combo == null || combo.isDisposed()) {
            return false;
        }

        int itemCount = combo.getItemCount();
        boolean isIndexValid = (index == -1) || (index >= 0 && index < itemCount);

        // 2. 处理选中逻辑（仅当索引有效时）
        if (isIndexValid) {
            if (index == -1) {
                combo.deselectAll(); // 取消所有选中
            } else {
                combo.select(index); // 选中指定索引的选项
            }
            return true;
        }

        // 3. 索引无效时返回失败
        return false;
    }

	/**
     * 为按钮添加单击事件监听
     * 
     * @param button   目标按钮控件
     * @param callback 事件触发时的回调函数，参数为SelectionEvent
     * 
     * 用法示例：
     * Button saveBtn = new Button(parent, SWT.PUSH);
     * SWTEventManager.addButtonClickListener(saveBtn, this::handleSave);
     * 
     * private void handleSave(SelectionEvent e) {
     *     // 处理保存逻辑
     * }
     */
    public static void addButtonClickListener(Button button, Consumer<SelectionEvent> callback) {
        validateControl(button);
        validateCallback(callback);

        button.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                if (!button.isDisposed()) {
                    callback.accept(e);
                }
            }
        });
    }

    /**
     * 为表格添加单击事件监听（选中行时触发）
     * 
     * @param table    目标表格控件
     * @param callback 事件触发时的回调函数，参数为SelectionEvent，包含选中信息
     * 
     * 用法示例：
     * Table dataTable = new Table(parent, SWT.BORDER | SWT.FULL_SELECTION);
     * SWTEventManager.addTableClickListener(dataTable, this::handleTableSelect);
     * 
     * private void handleTableSelect(SelectionEvent e) {
     *     int selectedIndex = dataTable.getSelectionIndex();
     *     if (selectedIndex != -1) {
     *         System.out.println("选中第" + selectedIndex + "行");
     *         // 处理表格行选中逻辑
     *     }
     * }
     */
    public static void addTableClickListener(Table table, Consumer<SelectionEvent> callback) {
        validateControl(table);
        validateCallback(callback);

        table.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                // 过滤表格头部点击（只处理行选中事件）
                if (e.item != null && !table.isDisposed()) {
                    callback.accept(e);
                }
            }
        });
    }

    /**
     * 为控件添加双击事件监听
     * 
     * @param control  目标控件（如Table、Tree等）
     * @param callback 事件触发时的回调函数，参数为MouseEvent
     * 
     * 用法示例：
     * Table dataTable = new Table(parent, SWT.BORDER);
     * SWTEventManager.addDoubleClickListener(dataTable, this::handleTableDoubleClick);
     */
    public static void addDoubleClickListener(Control control, Consumer<MouseEvent> callback) {
        validateControl(control);
        validateCallback(callback);

        control.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseDoubleClick(MouseEvent e) {
                if (!control.isDisposed()) {
                    callback.accept(e);
                }
            }
        });
    }

    /**
     * 为Combo下拉框添加选择事件监听
     * 
     * @param combo    目标Combo控件
     * @param callback 事件触发时的回调函数，参数为SelectionEvent
     * 
     * 用法示例：
     * Combo typeCombo = new Combo(parent, SWT.READ_ONLY);
     * SWTEventManager.addComboSelectionListener(typeCombo, this::handleTypeChange);
     */
    public static void addComboSelectionListener(Combo combo, Consumer<SelectionEvent> callback) {
        validateControl(combo);
        validateCallback(callback);

        combo.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                if (!combo.isDisposed()) {
                    callback.accept(e);
                }
            }
        });
    }

    /**
     * 为文本控件添加内容变化事件监听
     * 
     * @param control  目标文本控件
     * @param callback 事件触发时的回调函数，参数为ModifyEvent
     * 
     * 用法示例：
     * Text nameText = new Text(parent, SWT.BORDER);
     * SWTEventManager.addTextModifyListener(nameText, this::handleTextChange);
     */
    public static void addTextModifyListener(Text control, Consumer<ModifyEvent> callback) {
        validateControl(control);
        validateCallback(callback);

        control.addModifyListener(e -> {
            if (!control.isDisposed()) {
                callback.accept(e);
            }
        });
    }

    /**
     * 为控件添加焦点获取事件监听
     * 
     * @param control  目标控件
     * @param callback 事件触发时的回调函数，参数为FocusEvent
     */
    public static void addFocusGainListener(Control control, Consumer<FocusEvent> callback) {
        validateControl(control);
        validateCallback(callback);

        control.addFocusListener(new FocusAdapter() {
            @Override
            public void focusGained(FocusEvent e) {
                if (!control.isDisposed()) {
                    callback.accept(e);
                }
            }
        });
    }

    /**
     * 验证控件是否有效（非null且未释放）
     */
    private static void validateControl(Widget widget) {
        if (widget == null || widget.isDisposed()) {
            throw new IllegalArgumentException("控件不能为空或已释放（Disposed）");
        }
    }

    /**
     * 验证回调函数是否为null
     */
    private static void validateCallback(Object callback) {
        if (callback == null) {
            throw new IllegalArgumentException("回调函数不能为空");
        }
    }
}
